home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
misc
/
TownMaze.lha
/
TownMaze
/
src.lzh
/
makestreet.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-04
|
9KB
|
289 lines
/*
** makestreet.c Copyright 1991 Kent Paul Dolan,
** Mountain View, CA, USA 94039-0755
**
** Written to satisfy an inquiry on USENet's rec.games.programmer newsgroup.
** May be freely used or modified in any non-commercial work. Copyrighted
** only to prevent patenting by someone else.
*/
#include <stdio.h>
#include "townmaze.h"
#include "townproto.h"
#ifdef __STDC__
int makestreet(int chosencell,int streetid,int streetpoints)
#else
int makestreet(chosencell,streetid,streetpoints)
int chosencell,streetid, streetpoints;
#endif
{
int choseni, chosenj;
int nhbrid, nextnhbrid, thirdnhbrid;
int streetwalk, highstreetnum, lowstreetnum;
int canstraighten;
/*
** Check that a street isn't going in next to an unused cell; if it is,
** mark it dead, instead if it's live; in any case, refuse to do it.
*/
for (nhbrid = 0; nhbrid < 4; nhbrid++)
{
if (nhbrexists(chosencell,nhbrid))
if (statlist[nhbris(chosencell,nhbrid)].status == UNUSED)
{
if (statlist[chosencell].status == LIVE)
movefromto(&live,&livect,&dead,&deadct,DEAD,chosencell);
return(1==0);
}
}
/*
** Check for and abide by straightness control
*/
if ((mazestraightness > 0) && (streetpoints == -1))
if ((RANDOM()%1000) < mazestraightness)
{
canstraighten = (1==0);
for (nhbrid = 0; nhbrid < 4; nhbrid++)
if (nhbrexists(chosencell,nhbrid))
if (statlist[nhbris(chosencell,nhbrid)].streetdir ==
((nhbrid+2)%4))
canstraighten = (1==1);
if (!canstraighten) return(1==0);
}
/*
** Update the chosen cell in the status list
*/
switch (statlist[chosencell].status)
{
case UNUSED:
case STREET:
fprintf(stderr,"error picking street; bad cell status %d\n",
statlist[chosencell].status);
freespace();
exit(1);
break;
case LIVE:
/* fprintf(stderr,"moving cell %d from live to street\n",chosencell); */
movefromto(&live,&livect,&street,&streetct,STREET,chosencell);
break;
case DEAD:
/* fprintf(stderr,"moving cell %d from dead to street\n",chosencell); */
movefromto(&dead,&deadct,&street,&streetct,STREET,chosencell);
break;
case ISOLATED:
/* fprintf(stderr,"moving cell %d from isolated to street\n",chosencell);*/
movefromto(&isolated,&isolatedct,&street,&streetct,STREET,chosencell);
break;
default:
fprintf(stderr,"unexpected chosencell status in makegates %d\n",
statlist[chosencell].status);
}
/*
** Give the street the required streetid, either new or continuing an
** existing street.
*/
statlist[chosencell].streetnum = streetid;
/*
** Update the chosen cell on the map.
*/
choseni = chosencell / (mazewidth/2);
chosenj = chosencell % (mazewidth/2);
choseni = 2 * choseni + 1;
chosenj = 2 * chosenj + 1;
cmaze[choseni - 1][chosenj] = HDOOR;
cmaze[choseni][chosenj + 1] = VDOOR;
cmaze[choseni + 1][chosenj] = HDOOR;
cmaze[choseni][chosenj - 1] = VDOOR;
/*
** Update the neighbors of the new street cell;
*/
for (nhbrid = 0; nhbrid < 4; nhbrid++)
{
if (nhbrexists(chosencell,nhbrid))
switch (statlist[nhbris(chosencell,nhbrid)].status)
{
case UNUSED:
fprintf(stderr,
"logic error; tried to put a street beside an unused cell\n");
showdebugmaze();
freespace();
exit(1);
break;
case STREET:
switch (nhbrid) /* change the door to a passage, adopt a continuing */
{ /* direction from a neighbor street */
case 0:
cmaze[choseni - 1][chosenj] = BLANK;
if (statlist[nhbris(chosencell,nhbrid)].streetdir == 2)
statlist[chosencell].streetdir = 2;
break;
case 1:
cmaze[choseni][chosenj + 1] = BLANK;
if (statlist[nhbris(chosencell,nhbrid)].streetdir == 3)
statlist[chosencell].streetdir = 3;
break;
case 2:
cmaze[choseni + 1][chosenj] = BLANK;
if (statlist[nhbris(chosencell,nhbrid)].streetdir == 0)
statlist[chosencell].streetdir = 0;
break;
case 3:
cmaze[choseni][chosenj - 1] = BLANK;
if (statlist[nhbris(chosencell,nhbrid)].streetdir == 1)
statlist[chosencell].streetdir = 1;
break;
default:
fprintf(stderr,"bad nhbrid in nhbr update street switch case\n");
/* The above should be impossible; nhbrexists and nhbris already */
/* both checked for this problem */
showdebugmaze();
freespace();
exit(1);
}
if (statlist[chosencell].streetnum !=
statlist[nhbris(chosencell,nhbrid)].streetnum)
{
/*
** Two different streets have met; merge their streetids and decrement the
** streetcount.
*/
lowstreetnum =
( ( statlist[chosencell].streetnum >
statlist[nhbris(chosencell,nhbrid)].streetnum )
? statlist[nhbris(chosencell,nhbrid)].streetnum
: statlist[chosencell].streetnum
);
highstreetnum =
( ( statlist[chosencell].streetnum <
statlist[nhbris(chosencell,nhbrid)].streetnum )
? statlist[nhbris(chosencell,nhbrid)].streetnum
: statlist[chosencell].streetnum
);
streetwalk = street;
while (streetwalk != NOPOINTER)
{
if (statlist[streetwalk].streetnum == highstreetnum)
statlist[streetwalk].streetnum = lowstreetnum;
streetwalk = statlist[streetwalk].next;
}
streetnumct--;
}
break;
case DEAD: /* do nothing; that's why it's called dead */
break;
case LIVE:
movefromto(&live,&livect,&dead,&deadct,DEAD,nhbris(chosencell,nhbrid));
for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
== ISOLATED)
{
movefromto(&dead,&deadct,&live,&livect,LIVE,
nhbris(chosencell,nhbrid));
break;
}
break;
case ISOLATED:
movefromto(&isolated,&isolatedct,&dead,&deadct,DEAD,
nhbris(chosencell,nhbrid));
statlist[nhbris(chosencell,nhbrid)].status = DEAD;
/*
** Only let an isolated cell become live if it is interior; stops
** streets from running along the city wall, creating lots of gates.
** Don't make it live if it is next to an unused cell, either, since
** it can never become a street cell.
*/
if ( interiorcell(nhbris(chosencell,nhbrid))
&& (statlist[nhbris(nhbris(chosencell,nhbrid),0)].status != UNUSED)
&& (statlist[nhbris(nhbris(chosencell,nhbrid),1)].status != UNUSED)
&& (statlist[nhbris(nhbris(chosencell,nhbrid),2)].status != UNUSED)
&& (statlist[nhbris(nhbris(chosencell,nhbrid),3)].status != UNUSED)
)
for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
== ISOLATED)
{
movefromto(&dead,&deadct,&live,&livect,LIVE,
nhbris(chosencell,nhbrid));
break;
}
/*
** When an isolated cell stops being so, neighbors may stop being live
** that were depending on it for that status; we're not done!
*/
for (nextnhbrid = 0; nextnhbrid < 4; nextnhbrid++)
if (nhbrexists(nhbris(chosencell,nhbrid),nextnhbrid))
if (statlist[nhbris(nhbris(chosencell,nhbrid),nextnhbrid)].status
== LIVE)
{
movefromto(&live,&livect,&dead,&deadct,DEAD,
nhbris(nhbris(chosencell,nhbrid),nextnhbrid));
for (thirdnhbrid =0; thirdnhbrid <4; thirdnhbrid++)
{
if (nhbrexists(nhbris(nhbris(chosencell,
nhbrid),
nextnhbrid),
thirdnhbrid))
if (statlist[nhbris(nhbris(nhbris(chosencell,
nhbrid),
nextnhbrid),
thirdnhbrid)].status
== ISOLATED)
{
movefromto(&dead,&deadct,&live,&livect,LIVE,
nhbris(nhbris(chosencell,nhbrid),nextnhbrid));
break;
}
}
}
break;
default:
fprintf(stderr,"bad statlist[%d].status entry %d\n",
nhbris(chosencell,nhbrid),
statlist[nhbris(chosencell,nhbrid)].status);
showdebugmaze();
freespace();
exit(1);
}
}
if (statlist[chosencell].streetdir == -1)
if (streetpoints != -1)
statlist[chosencell].streetdir = streetpoints;
else
{
for (nhbrid = 0; nhbrid < 4; nhbrid++)
{
if (nhbrexists(chosencell,nhbrid))
if (statlist[nhbris(chosencell,nhbrid)].status == STREET)
{
statlist[chosencell].streetdir = ((nhbrid +2)%4);
break;
}
}
}
/* showdebugmaze(); */
return(1==1);
}